local view = require "views.view"

---@class view_builder: view
---@field builder fun(): view
local view_builder = view:new_view_type()

---@class view_builder.renderer: view.renderer
---@field private _valid_cache boolean
---@field private _builder_result_view view
---@field private _builder_result_view_renderer view.renderer
view_builder.renderer = view.renderer:new_renderer_type()

---@param builder fun(): view
function view_builder:__call(builder)
    assert(builder)

    return self:set_view_prototype( { builder = builder } )
end

function view_builder:create_renderer_instance()
    local result_view = self.builder()

    return self:set_renderer_prototype({
        _valid_cache = true,
        _builder_result_view = result_view,
        _builder_result_view_renderer = result_view:create_renderer_instance()
    })
end

---@param constraints constraints
---@param view view_builder
function view_builder.renderer:layout(constraints, view)
    if not self._valid_cache then
        local result_view = view.builder()
        self._builder_result_view = result_view
        if not result_view:is_same_view_type(self._builder_result_view) then
            self._builder_result_view_renderer:destroy()
            self._builder_result_view_renderer = result_view:create_renderer_instance()
        end

        self._valid_cache = true
    end

    return self._builder_result_view_renderer:layout(
        constraints,
        self._builder_result_view
    )
end

function view_builder.renderer:render(render_rect, view)
    self._builder_result_view_renderer:render(render_rect, self._builder_result_view)
    self._valid_cache = false
end

function view_builder.renderer:destroy()
    self._builder_result_view_renderer:destroy()
end

return view_builder
